package Day_0226.ObserverPattern;

import java.util.Vector;

/**
 * @author zxc
 * @date 2023/02/27 10:45
 **/
public class ObserverPattern {
    public static void main(String[] args) {
        /**
         * 观察者模式
         * ===》
         * 1.观察者模式的概念
         * ===》
         * （1）先讲什么是行为性模型，行为型模式关注的是系统中对象之间的相互交互，
         *  解决系统在运行时对象之间的相互通信和协作，进一步明确对象的职责。
         * （2）观察者模式，是一种行为性模型，又叫发布-订阅模式，他定义对象之间一种一对多的依赖关系，
         *  使得当一个对象改变状态，则所有依赖于它的对象都会得到通知并自动更新。
         *
         * 2.模式的职责
         * ===》
         * 观察者模式主要用于1对N的通知。当一个对象的状态变化时，需要及时告知一系列对象，令他们做出相应。
         * 实现有两种方式：
         *（1）推：每次都会把通知以广播的方式发送给所有观察者，所有的观察者只能被动接收。
         *（2）拉：观察者只要知道有情况即可，至于什么时候获取内容，获取什么内容，都可以自主决定。
         * ===》
         * 总结 ：
         * （1）观察者模式，主要适用于1对N的通知;
         * （2）若是被观察者的状态发生变化的话，则会将该状态变化直接广播给所有观察者;
         * （3）同时，观察者只需要直到被观察者发生变化这个消息，而对于获取状态变化的内容，则由观察者来决定;
         *
         * 3.观察者模式应用场景
         * （1）关联行为场景，需要注意的是，关联行为是可拆分的，而不是“组合”关系。事件多级触发场景。
         * （2）跨系统的消息交换场景，如消息队列、事件总线的处理机制。
         *
         * ===》
         * 总结 ：
         * （1）观察者模式，适用于发布订阅模式（即，1对N的广播通信）;
         * （2）首先，定义一个观察者接口，后面使用具体观察者去继承该接口;
         * （3）定义主题类（即，被观察者），若是该主题中状态发生变化的话在，则会导致所有订阅该主题的观察者都收到该主题状态发生变化的消息;
         * （4）主题类中，维护了一个观察者集合，同时定义了 注册观察者 && 删除观察者 && 通知所有订阅该主题的观察者;
         * （5）具体主题，是继承了该主题类（即，为该主题类的子类）;
         *  具体主题中，定义了该主题的具体状态 && 若是该主题的状态发生变化的话，则会通知所有订阅该主题的观察者;
         *
         *
         */
    }
}
//观察者的接口，用来存放观察者共有方法
interface Observer {
    // 观察者方法
    void update(int state);
}
// 具体观察者
class ObserverImpl implements Observer {
    // 具体观察者的属性
    private int myState;
    public void update(int state) {
        myState=state;
        System.out.println("收到消息,myState值改为："+state);
    }
    public int getMyState() {
        return myState;
    }
}
//定义主题，以及定义观察者数组，并实现增、删及通知操作。
class Subjecct {
    //观察者的存储集合，不推荐ArrayList，线程不安全，
    private Vector<Observer> list = new Vector<>();
    // 注册观察者方法
    public void registerObserver(Observer obs) {
        list.add(obs);
    }
    // 删除观察者方法
    public void removeObserver(Observer obs) {
        list.remove(obs);
    }
    // 通知所有的观察者更新
    public void notifyAllObserver(int state) {
        for (Observer observer : list) {
            observer.update(state);
        }
    }
}
//具体主题
class RealObserver extends Subjecct {
    //被观察对象的属性
    private int state;
    public int getState(){
        return state;
    }
    public void setState(int state){
        this.state=state;
        //主题对象(目标对象)值发生改变
        this.notifyAllObserver(state);
    }
}
class Client {
    public static void main(String[] args) {
        // 目标对象
        RealObserver subject = new RealObserver();
        // 创建多个观察者
        ObserverImpl obs1 = new ObserverImpl();
        ObserverImpl obs2 = new ObserverImpl();
        ObserverImpl obs3 = new ObserverImpl();
        // 注册到观察队列中
        subject.registerObserver(obs1);
        subject.registerObserver(obs2);
        subject.registerObserver(obs3);
        // 改变State状态
        subject.setState(300);
        System.out.println("obs1观察者的MyState状态值为：" + obs1.getMyState());
        System.out.println("obs2观察者的MyState状态值为：" + obs2.getMyState());
        System.out.println("obs3观察者的MyState状态值为：" + obs3.getMyState());
        // 改变State状态
        subject.setState(400);
        System.out.println("obs1观察者的MyState状态值为：" + obs1.getMyState());
        System.out.println("obs2观察者的MyState状态值为：" + obs2.getMyState());
        System.out.println("obs3观察者的MyState状态值为：" + obs3.getMyState());
    }
}
